import InterceptorManager from '../core/InterceptorManager'

export type Method =
  | 'get'
  | 'GET'
  | 'delete'
  | 'DELETE'
  | 'head'
  | 'HEAD'
  | 'options'
  | 'OPTIONS'
  | 'post'
  | 'POST'
  | 'put'
  | 'PUT'
  | 'patch'
  | 'PATCH'

export interface Interceptors {
  request: InterceptorManager<RolechRequestConfig>
  response: InterceptorManager<RolechResponse>
}
export interface Rolech {
  interceptors: Interceptors
  request<T = any>(config: RolechRequestConfig): RolechPromise<T>
  get<T = any>(url: string, config?: RolechRequestConfig): RolechPromise<T>
  delete<T = any>(url: string, config?: RolechResponse): RolechPromise<T>
  head<T = any>(url: string, config?: RolechResponse): RolechPromise<T>
  options<T = any>(url: string, config?: RolechResponse): RolechPromise<T>
  post<T = any>(url: string, data?: any, config?: RolechResponse): RolechPromise<T>
  put<T = any>(url: string, data?: any, config?: RolechResponse): RolechPromise<T>
  patch<T = any>(url: string, data?: any, config?: RolechResponse): RolechPromise<T>
}

export interface RolechInstance extends Rolech {
  <T = any>(config: RolechRequestConfig): RolechPromise<T>
  <T = any>(url: string, config?: RolechRequestConfig): RolechPromise<T>
}
export interface RolechRequestConfig {
  url?: string
  method?: Method
  data?: any
  params?: any
  headers?: any
  responseType?: XMLHttpRequestResponseType
  timeout?: number
}

export interface RolechResponse<T = any> {
  data: T
  status: number
  statusText: string
  headers: any
  config: RolechRequestConfig
  request: any
}

export interface RolechPromise<T = any> extends Promise<RolechResponse<T>> {}

export interface RolechError extends Error {
  config: RolechRequestConfig
  code?: string
  request?: any
  response?: RolechResponse
  isRolechError: boolean
}
export interface ResolvedFn<T = any> {
  (val: T): T | Promise<T>
}

export interface RejectedFn {
  (error: any): any
}
export interface RolechInterceptorManager<T> {
  use(resolved: ResolvedFn<T>, rejected?: RejectedFn): number
}
